#include "Render/WindowInteractorStyle.h"

#include "vtkCallbackCommand.h"
#include "vtkCamera.h"
#include "vtkMath.h"
#include "vtkMatrix3x3.h"
#include "vtkObjectFactory.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "Core/MainWindow.h"
#include "vtkActor.h"
#include "vtkProperty.h"
#include "vtkPropPicker.h"
#include "Core/RWTools.h"
#include <TopoDS_Vertex.hxx>
#include <BRep_Tool.hxx>
#include "TopoDS.hxx"
#include <TopoDS_Edge.hxx>
#include "FeatureShape/HistoryManager.h"
#include <vtkTransform.h>
#include "vtkTipsCoordinate.h"

VTK_ABI_NAMESPACE_BEGIN
vtkStandardNewMacro(WindowInteractorStyle);

WindowInteractorStyle::WindowInteractorStyle()
{
	MotionFactor = 10.0;
	HighlightActor = nullptr;
	m_mainWindow = nullptr;

	LastPickedActor = nullptr;
	LastPickedProperty->Delete();
}

WindowInteractorStyle::~WindowInteractorStyle() = default;

static void ClearHighlightAndSelection(NCollection_DataMap<IVtk_IdType, Handle(QIVtkSelectionPipeline) > pipelinesMap,
	const Standard_Boolean doHighlighting, const Standard_Boolean doSelection)
{
	if (!doHighlighting && !doSelection)
	{
		return;
	}

	NCollection_DataMap<IVtk_IdType, Handle(QIVtkSelectionPipeline) >::Iterator pIt(pipelinesMap);
	for (; pIt.More(); pIt.Next())
	{
		const Handle(QIVtkSelectionPipeline)& pipeline = pIt.Value();

		if (doHighlighting)
		{
			pipeline->ClearHighlightFilters();
		}

		if (doSelection)
		{
			pipeline->ClearSelectionFilters();
		}
	}
}

void WindowInteractorStyle::OnMouseMove()
{
	int x = this->Interactor->GetEventPosition()[0];
	int y = this->Interactor->GetEventPosition()[1];

	//std::cout << "MouseMove: " << x << ", " << y << std::endl;
	m_mainWindow->MouseMove(x, y);

	this->MoveTo(x, y);

	switch (this->State)
	{
	case VTKIS_ROTATE:
		this->FindPokedRenderer(x, y);
		this->Rotate();
		this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
		break;

	case VTKIS_PAN:
		this->FindPokedRenderer(x, y);
		this->Pan();
		this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
		break;

	//case VTKIS_DOLLY:
	//	this->FindPokedRenderer(x, y);
	//	this->Dolly();
	//	this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
	//	break;
	}

	// 使用vtk拾取器检测鼠标下的对象
	if (this->CurrentRenderer != nullptr)
	{
		this->FindPokedRenderer(x, y);
		vtkRenderWindowInteractor* rwi = this->Interactor;
		vtkAbstractPropPicker* picker = vtkAbstractPropPicker::SafeDownCast(rwi->GetPicker());
		picker->Pick(x, y, 0, this->CurrentRenderer);

		// 获取拾取到的 actor
		vtkActor* actor = picker->GetActor();

		if (actor)
		{
			m_mainWindow->PickActor(actor);
		}
		Handle(QIVtkSelectionPipeline) PickPipeline = actor ? m_mainWindow->GetActorsOuterPipeline(actor) : nullptr;

		// 点选择器所需的提示actor
		if (m_mainWindow && tempSphereActor)
		{
			tempSphereActor->SetVisibility(false);
		}
		else if (m_mainWindow)
		{
			tempSphereActor = m_mainWindow->CreateTempSphereActor(0.02f, gp_Pnt());
			tempSphereActor->SetVisibility(false);
			tempSphereActor->SetPickable(false);
		}

		double pos[3];
		picker->GetPickPosition(pos);
		gp_Pnt aPos(pos[0], pos[1], pos[2]);
		if (PickPipeline && _currentSelectionMode == SM_Vertex && tempSphereActor)
		{
			std::vector<gp_Pnt> allPoints;
			for (auto& pair : PickPipeline->m_points) 
			{
				if (!_selectedVertexTypes.count(pair.first))
				{
					continue;
				}
				allPoints.insert(allPoints.end(), pair.second.begin(), pair.second.end());
			}

			gp_Pnt findPoint;
			bool bFind = ContainsVertex(findPoint, allPoints, aPos, 0.01);
			if (bFind)
			{
				tempSphereActor->SetPosition(findPoint.X(), findPoint.Y(), findPoint.Z());
				tempSphereActor->SetVisibility(true);
			}
		}

		// 如果鼠标下的 actor 发生变化，则更新颜色
		if (this->HighlightActor != PickPipeline)
		{
			// 恢复上一个高亮的 actor 的颜色
			if (this->HighlightActor)
			{
				this->HighlightActor->Actor()->GetProperty()->SetColor(ContainsActor(selectActors,this->HighlightActor) ? Colors::ActorSelected : Colors::ActorCreated);
			}
			
			// 更新当前高亮的 actor 并改变颜色
			this->HighlightActor = PickPipeline;
			if (this->HighlightActor && !ContainsActor(selectActors, this->HighlightActor))
			{
				this->HighlightActor->Actor()->GetProperty()->SetColor(Colors::ActorHover);
			}

			// 重新渲染场景
			this->GetInteractor()->GetRenderWindow()->Render();
		}
	}
}

void WindowInteractorStyle::OnLeftButtonDown()
{
	lastPos[0] = this->GetInteractor()->GetEventPosition()[0];
	lastPos[1] = this->GetInteractor()->GetEventPosition()[1];

	m_mainWindow->OnLeftButtonDown();

	// 点击Hovered actor
	if (this->HighlightActor && !ContainsActor(selectActors, this->HighlightActor) && m_mainWindow)
	{
		SelectActor(this->HighlightActor);
	}

	// 点击空白处——如果Sub Widget需要选中Actor则不会clear
	if (selectActors.size() && this->HighlightActor.IsNull() &&
		m_mainWindow && !m_mainWindow->IsSubWidgetSelected())
	{
		for (Handle(QIVtkSelectionPipeline) pipeline : selectActors)
		{
			pipeline->Actor()->GetProperty()->SetColor(Colors::ActorCreated);
		}
		selectActors.clear();
		ClearHighlightAndSelection(_shapePipelinesMap, Standard_True, Standard_True);
		//setSelectionMode(SM_None);
		//std::cout << "Clear Selection" << std::endl;
	}
}

void WindowInteractorStyle::OnLeftButtonUp()
{
	int* clickPos = this->GetInteractor()->GetEventPosition();

	//if mouse moved, is a DragEvent.
	if (clickPos[0] == lastPos[0] && clickPos[1] == lastPos[1]) 
	{
		if (this->Interactor->GetShiftKey() && _canMultiSelect)
		{
			// Append new selection to the current one
			this->OnSelection(Standard_True);
		}
		else 
		{
			// Clear previous selection
			this->OnSelection(Standard_False);
		}
	}
	_qvtkRenderWindow->Render();
}

void WindowInteractorStyle::OnMiddleButtonDown()
{
	this->FindPokedRenderer(this->Interactor->GetEventPosition()[0], this->Interactor->GetEventPosition()[1]);
	if (this->CurrentRenderer == nullptr)
	{
		return;
	}

	this->GrabFocus(this->EventCallbackCommand);
	if (this->Interactor->GetShiftKey())
	{
		this->StartPan();
	}
	else if(!bIsIn2DMode)
	{
		this->StartRotate();
	}
}

void WindowInteractorStyle::OnMiddleButtonUp()
{
	switch (this->State)
	{
	case VTKIS_PAN:
		this->EndPan();
		
		break;
	case VTKIS_ROTATE:
		this->EndRotate();
		break;
	}

	if (this->Interactor)
	{
		this->ReleaseFocus();
	}
}

void WindowInteractorStyle::OnRightButtonDown()
{
	int* clickPos = this->GetInteractor()->GetEventPosition();
	m_mainWindow->onRightClickMenu();

}

void WindowInteractorStyle::OnRightButtonUp()
{
}

void WindowInteractorStyle::OnMouseWheelForward()
{
	this->FindPokedRenderer(this->Interactor->GetEventPosition()[0], this->Interactor->GetEventPosition()[1]);
	if (this->CurrentRenderer == nullptr)
	{
		return;
	}

	this->GrabFocus(this->EventCallbackCommand);
	this->StartDolly();
	double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
	this->Dolly(pow(1.1, factor));
	this->EndDolly();
	this->ReleaseFocus();
}

void WindowInteractorStyle::OnMouseWheelBackward()
{
	this->FindPokedRenderer(this->Interactor->GetEventPosition()[0], this->Interactor->GetEventPosition()[1]);
	if (this->CurrentRenderer == nullptr)
	{
		return;
	}

	this->GrabFocus(this->EventCallbackCommand);
	this->StartDolly();
	double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
	this->Dolly(pow(1.1, factor));
	this->EndDolly();
	this->ReleaseFocus();
}

void WindowInteractorStyle::Dolly()
{
	if (this->CurrentRenderer == nullptr)
	{
		return;
	}

	vtkRenderWindowInteractor* rwi = this->Interactor;
	double* center = this->CurrentRenderer->GetCenter();
	int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
	double dyf = this->MotionFactor * dy / center[1];
	this->Dolly(pow(1.1, dyf));
}

void WindowInteractorStyle::Pan()
{
	if (this->CurrentRenderer == nullptr)
	{
		return;
	}

	vtkRenderWindowInteractor* rwi = this->Interactor;

	double viewFocus[4], focalDepth, viewPoint[3];
	double newPickPoint[4], oldPickPoint[4], motionVector[3];

	// Calculate the focal depth since we'll be using it a lot

	vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
	camera->GetFocalPoint(viewFocus);
	this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2], viewFocus);
	focalDepth = viewFocus[2];

	this->ComputeDisplayToWorld(rwi->GetEventPosition()[0], rwi->GetEventPosition()[1], focalDepth, newPickPoint);

	// Has to recalc old mouse point since the viewport has moved,
	// so can't move it outside the loop

	this->ComputeDisplayToWorld(rwi->GetLastEventPosition()[0], rwi->GetLastEventPosition()[1], focalDepth, oldPickPoint);

	// Camera motion is reversed

	motionVector[0] = oldPickPoint[0] - newPickPoint[0];
	motionVector[1] = oldPickPoint[1] - newPickPoint[1];
	motionVector[2] = oldPickPoint[2] - newPickPoint[2];

	camera->GetFocalPoint(viewFocus);
	camera->GetPosition(viewPoint);
	camera->SetFocalPoint(motionVector[0] + viewFocus[0], motionVector[1] + viewFocus[1], motionVector[2] + viewFocus[2]);

	camera->SetPosition(motionVector[0] + viewPoint[0], motionVector[1] + viewPoint[1], motionVector[2] + viewPoint[2]);

	if (rwi->GetLightFollowCamera())
	{
		this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
	}

	rwi->Render();
}

void WindowInteractorStyle::Rotate()
{
	if (this->CurrentRenderer == nullptr)
	{
		return;
	}

	vtkRenderWindowInteractor* rwi = this->Interactor;

	int dx = rwi->GetEventPosition()[0] - rwi->GetLastEventPosition()[0];
	int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];

	const int* size = this->CurrentRenderer->GetRenderWindow()->GetSize();

	double delta_elevation = -20.0 / size[1];
	double delta_azimuth = -20.0 / size[0];

	double rxf = dx * delta_azimuth * this->MotionFactor;
	double ryf = dy * delta_elevation * this->MotionFactor;

	vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();

	// 垂直轴
	camera->Azimuth(rxf);
	// 水平轴
	camera->Elevation(ryf);
	camera->OrthogonalizeViewUp();

	if (this->AutoAdjustCameraClippingRange)
	{
		this->CurrentRenderer->ResetCameraClippingRange();
	}

	if (rwi->GetLightFollowCamera())
	{
		this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
	}

	rwi->Render();
}

void WindowInteractorStyle::GetVertexPickerTargetPos(bool& bIsPick, gp_Pnt& Pos)
{
	if (!tempSphereActor)
	{
		return;
	}

	bIsPick = tempSphereActor->GetVisibility();
	double tempPos[3];
	tempSphereActor->GetPosition(tempPos);
	Pos = gp_Pnt(tempPos[0], tempPos[1], tempPos[2]);
}

void WindowInteractorStyle::SetMaxSelectedActors(uint maxSelectedActors)
{
	_maxSelectedActors = maxSelectedActors;
}

void WindowInteractorStyle::ResetMaxSelectedActors()
{
	_maxSelectedActors = _defaultMaxSelectedActors;
}

void WindowInteractorStyle::SelectActor(Handle(QIVtkSelectionPipeline) pipeline, bool bClearSelected)
{
	// 超过了最大选择数目
	if (selectActors.size() >= _maxSelectedActors)
	{
		return;
	}

	if (bClearSelected)
	{
		ClearSelectedActors();
	}

	selectActors.push_back(pipeline);

	pipeline->Actor()->GetProperty()->SetColor(Colors::ActorSelected);

	// 重新渲染场景
	this->GetInteractor()->GetRenderWindow()->Render();

	// 发送信号
	m_mainWindow->SelectedActor(pipeline.get());
}

void WindowInteractorStyle::SetStandardView(vtkRenderer* renderer, EViewStytle viewStytle)
{
	vtkCamera* camera = renderer->GetActiveCamera();

	static const double defaultDistance = 10.0;

	double parallelScale = 1.f;
	if (renderer->GetActors()->GetNumberOfItems() > 0)
	{
		double bounds[6];
		renderer->ComputeVisiblePropBounds(bounds);
		parallelScale = std::max({ bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4] }) * 1.2;
	}

	if (viewStytle == EViewStytle::frontView) {
		camera->SetPosition(0, 0, defaultDistance);
		camera->SetViewUp(0, 1, 0);
	}
	else if (viewStytle == EViewStytle::backView) {
		camera->SetPosition(0, 0, -defaultDistance);
		camera->SetViewUp(0, 1, 0);
	}
	else if (viewStytle == EViewStytle::leftView) {
		camera->SetPosition(-defaultDistance, 0, 0);
		camera->SetViewUp(0, 1, 0);
	}
	else if (viewStytle == EViewStytle::rightView) {
		camera->SetPosition(defaultDistance, 0, 0);
		camera->SetViewUp(0, 1, 0);
	}
	else if (viewStytle == EViewStytle::topView) {
		camera->SetPosition(0, defaultDistance, 0);
		camera->SetViewUp(0, 0, -1); // 避免视图翻转
	}
	else if (viewStytle == EViewStytle::bottomView) {
		camera->SetPosition(0, -defaultDistance, 0);
		camera->SetViewUp(0, 0, 1);
	}
	else if (viewStytle == EViewStytle::positiveTriaxialView) {
		camera->SetPosition(defaultDistance, defaultDistance, defaultDistance);
		camera->SetViewUp(-1, 1, 0); // 调整 ViewUp 以对齐三轴
	}

	camera->SetFocalPoint(0, 0, 0);
	camera->OrthogonalizeViewUp(); // 确保视图方向正交
	camera->SetParallelScale(parallelScale);
	renderer->ResetCameraClippingRange();
	renderer->GetRenderWindow()->Render();
}

void WindowInteractorStyle::SetFitView(vtkRenderer* renderer)
{
	double parallelScale = 1.f;
	double bounds[6];
	double boundsCenter[3] = { 0,0,0 };
	if (renderer->GetActors()->GetNumberOfItems() > 0)
	{
		renderer->ComputeVisiblePropBounds(bounds);
		parallelScale = std::max({ bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4] }) * 1.2;
		boundsCenter[0] = (bounds[0] + bounds[1]) / 2.0;
		boundsCenter[1] = (bounds[2] + bounds[3]) / 2.0;
		boundsCenter[2] = (bounds[4] + bounds[5]) / 2.0;
	}
	vtkCamera* camera = renderer->GetActiveCamera();
	camera->SetFocalPoint(boundsCenter);
	camera->OrthogonalizeViewUp(); // 确保视图方向正交
	camera->SetParallelScale(parallelScale);
	renderer->ResetCameraClippingRange();
	renderer->GetRenderWindow()->Render();
}

void WindowInteractorStyle::Toggle2DMode(const gp_Pnt& focusCenter, const gp_Dir& N, const gp_Dir& R)
{
	static const double defaultDistance = 10.0;

	if (bIsIn2DMode)
	{
		return;
	}

	bIsIn2DMode = true;
	vtkRenderer* renderer =m_mainWindow->GetRenderer();
	vtkCamera* camera = renderer->GetActiveCamera();

	// 首先记录相机位置与 up 向量
	_lastCameraPos = gp_Pnt(camera->GetPosition()[0], camera->GetPosition()[1], camera->GetPosition()[2]);
	_lastCameraViewUp = gp_Dir(camera->GetViewUp()[0], camera->GetViewUp()[1], camera->GetViewUp()[2]);
	_lastFocalPoint = gp_Pnt(camera->GetFocalPoint()[0], camera->GetFocalPoint()[1], camera->GetFocalPoint()[2]);

	// center + N * defaultDistance
	gp_Pnt cameraPos = (focusCenter).Translated(defaultDistance * N);
	// N crossed R
	gp_Dir cameraViewUp = N.Crossed(R);
	camera->SetPosition(cameraPos.X(), cameraPos.Y(), cameraPos.Z());
	camera->SetViewUp(cameraViewUp.X(), cameraViewUp.Y(), cameraViewUp.Z());
	camera->SetFocalPoint(focusCenter.X(), focusCenter.Y(), focusCenter.Z());

	camera->OrthogonalizeViewUp(); // 确保视图方向正交
	renderer->ResetCameraClippingRange();
	renderer->GetRenderWindow()->Render();

	// 视角操作限制
}

void WindowInteractorStyle::ResetMode()
{
	if (!bIsIn2DMode)
	{
		return;
	}

	bIsIn2DMode = false;
	vtkRenderer* renderer = m_mainWindow->GetRenderer();
	vtkCamera* camera = renderer->GetActiveCamera();

	camera->SetPosition(_lastCameraPos.X(), _lastCameraPos.Y(), _lastCameraPos.Z());
	camera->SetViewUp(_lastCameraViewUp.X(), _lastCameraViewUp.Y(), _lastCameraViewUp.Z());
	camera->SetFocalPoint(_lastFocalPoint.X(), _lastFocalPoint.Y(), _lastFocalPoint.Z());

	camera->OrthogonalizeViewUp(); // 确保视图方向正交
	renderer->ResetCameraClippingRange();
	renderer->GetRenderWindow()->Render();
}

void WindowInteractorStyle::Dolly(double factor)
{
	if (this->CurrentRenderer == nullptr)
	{
		return;
	}

	vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
	if (camera->GetParallelProjection())
	{
		camera->SetParallelScale(camera->GetParallelScale() / factor);
	}
	else
	{
		camera->Dolly(factor);
		if (this->AutoAdjustCameraClippingRange)
		{
			this->CurrentRenderer->ResetCameraClippingRange();
		}
	}

	if (this->Interactor->GetLightFollowCamera())
	{
		this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
	}

	this->Interactor->Render();
}

void WindowInteractorStyle::OnChar()
{
	vtkRenderWindowInteractor* rwi = this->Interactor;
	if (rwi->GetControlKey() || rwi->GetAltKey())
	{
		// Ignore keys when modifiers (other than shift) are pressed.
		return;
	}
	// std::cout << "Key pressed: " << rwi->GetKeySym() << "Key Code: " << (int)rwi->GetKeyCode() << std::endl;
	if (rwi->GetKeyCode() == '\177' && m_mainWindow && !selectActors.empty())
	{
		ClearHighlightAndSelection(_shapePipelinesMap, Standard_True, Standard_True);

		this->HighlightActor = nullptr;

		m_mainWindow->onDeleteActionTriggered();
	}
}

void WindowInteractorStyle::setSelectionMode(IVtk_SelectionMode mode)
{
	if (_shapePipelinesMap.IsEmpty())
	{
		return;
	}

	if (mode == _currentSelectionMode)
	{
		return;
	}

	// 清空已选择的shape
	NCollection_DataMap<IVtk_IdType, IVtk_ShapeIdList*>::Iterator sIt(_selectedSubShapeIdsMap);
	for (; sIt.More(); sIt.Next())
	{
		IVtk_ShapeIdList* selectedSubShapeIds = sIt.Value();
		selectedSubShapeIds->Clear();
	}

	if (_selectedShapes.size())
	{
		_selectedShapes.clear();
		m_mainWindow->SelectedSubShapes(nullptr);
	}

	ClearHighlightAndSelection(_shapePipelinesMap, Standard_True, Standard_True);

	//清空所有的选择模式
	NCollection_DataMap<IVtk_IdType, Handle(QIVtkSelectionPipeline) >::Iterator pIt(_shapePipelinesMap);
	for (; pIt.More(); pIt.Next())
	{
		const Handle(QIVtkSelectionPipeline)& pipeline = pIt.Value();

		// Deactivate all current selection modes
		IVtk_SelectionModeList modeList = _occtpicker->GetSelectionModes(pipeline->Actor());

		for (IVtk_SelectionMode selMode : modeList)
		{
			_occtpicker->SetSelectionMode(selMode, false);
		}
	}
	// Set given selection mode
	if (mode == SM_None)
	{
		_occtpicker->SetSelectionMode(mode, false);
		_occtPickerEnabled = false;
	}
	else
	{
		_occtpicker->SetSelectionMode(mode, true);
		_occtPickerEnabled = true;

	}
	_currentSelectionMode = mode;
}

void WindowInteractorStyle::setCanMultiSelect(bool bCanMultiPick)
{
    _canMultiSelect = bCanMultiPick;
}

//void WindowInteractorStyle::setSelectionModeForActor(Handle(QIVtkSelectionPipeline) actor, IVtk_SelectionMode mode)
//{
//	// Set given selection mode
//	if (mode == SM_None)
//	{
//		_occtpicker->SetSelectionMode(actor->SelActor(), mode, false);
//		_occtpicker->SetSelectionMode(actor->HiliActor(), mode, false);
//	}
//	else
//	{
//		_occtpicker->SetSelectionMode(actor->SelActor(), mode, true);
//		_occtpicker->SetSelectionMode(actor->HiliActor(), mode, true);
//	}
//
//}

void WindowInteractorStyle::OnSelection(Standard_Boolean appendId)
{
	vtkSmartPointer<vtkActorCollection> anActorCollection = _occtpicker->GetPickedActors();

	if (anActorCollection)
	{
		auto res = anActorCollection->GetNumberOfItems();
		if (anActorCollection->GetNumberOfItems() != 0)
		{
			// Clear previous selection.
			ClearHighlightAndSelection(_shapePipelinesMap, Standard_False, Standard_True);
		}

		anActorCollection->InitTraversal();
		while (vtkActor* anActor = anActorCollection->GetNextActor())
		{
			IVtkTools_ShapeDataSource* aDataSource = IVtkTools_ShapeObject::GetShapeSource(anActor);
			if (!aDataSource)
			{
				continue;
			}

			IVtkOCC_Shape::Handle anOccShape = aDataSource->GetShape();

			if (anOccShape.IsNull())
			{
				continue;
			}

			IVtk_IdType aShapeID = anOccShape->GetId();

			Handle(Message_Messenger) anOutput = Message::DefaultMessenger();

			if (!_shapePipelinesMap.IsBound(aShapeID))
			{
				anOutput->SendWarning()
					<< "Warning: there is no VTK pipeline registered for picked shape"
					<< std::endl;
				continue;
			}

			const Handle(QIVtkSelectionPipeline)& pipeline = _shapePipelinesMap.Find(aShapeID);
			IVtk_ShapeIdList* selectedSubShapeIds = _selectedSubShapeIdsMap.Find(aShapeID);

			IVtkTools_SubPolyDataFilter* aFilter = pipeline->GetSelectionFilter();

			// Set the selected sub-shapes ids to subpolydata filter.
			IVtk_ShapeIdList aSubShapeIds;
			if (_currentSelectionMode == IVtk_SelectionMode::SM_Shape)
			{
				aSubShapeIds = _occtpicker->GetPickedShapesIds(Standard_False);
			}
			else
			{
				aSubShapeIds = _occtpicker->GetPickedSubShapesIds(aShapeID);
			}

			if (!appendId)
			{
				_selectedShapes.clear();
				selectedSubShapeIds->Clear();
			}

			for (auto shapeID : aSubShapeIds)
			{
				if (!selectedSubShapeIds->Contains(shapeID))
				{
					// If selected Ids list does not contain shape then append it.
					selectedSubShapeIds->Append(aSubShapeIds);
				}
				else
				{
					// Selecting the shape again causes deselecting it.
					selectedSubShapeIds->Remove(shapeID);
				}
			}

			// If selected Ids list is empty then any selection will not be made
			if (selectedSubShapeIds->IsEmpty())
			{
				// 判断pipeline是否可以直接转化为edge（edge的pipeline不存在SubShapeIds）
				if (pipeline->_shape.ShapeType() == TopAbs_EDGE)
				{
					_selectedShapes.push_back(pipeline->_shape);
					IVtk_ShapeIdList aSubIds;
					aFilter->SetDoFiltering(false);
					aFilter->SetData(aSubIds);
					if (!aFilter->GetInput())
					{
						aFilter->SetInputConnection(aDataSource->GetOutputPort());
					}
					aFilter->Modified();
					if (!pipeline.IsNull())
					{
						pipeline->Mapper()->Update();
					}
					// 发送选中信号
					m_mainWindow->SelectedSubShapes(pipeline.get());
				}
				// 判断pipeline是否可以直接转化为face
				if (pipeline->_shape.ShapeType() == TopAbs_FACE)
				{
					_selectedShapes.push_back(pipeline->_shape);
					// 发送选中信号
					m_mainWindow->SelectedSubShapes(pipeline.get());
				}
				return;
			}

			// Get ids of cells for picked subshapes
			IVtk_ShapeIdList aSubIds;
			IVtk_ShapeIdList::Iterator aMetaIds(*selectedSubShapeIds);
			_selectedShapes.clear();
			for (; aMetaIds.More(); aMetaIds.Next())
			{
				IVtk_ShapeIdList aSubSubIds = anOccShape->GetSubIds(aMetaIds.Value());
				const TopoDS_Shape& aSubShape = anOccShape->GetSubShape(aMetaIds.Value());
				_selectedShapes.push_back(aSubShape);
				aSubIds.Append(aSubSubIds);
			}
			aFilter->SetDoFiltering(!aSubIds.IsEmpty());
			aFilter->SetData(aSubIds);
			if (!aFilter->GetInput())
			{
				aFilter->SetInputConnection(aDataSource->GetOutputPort());
			}
			aFilter->Modified();

			if (!pipeline.IsNull())
			{
				pipeline->Mapper()->Update();
			}

			// 发送选中信号
			m_mainWindow->SelectedSubShapes(pipeline.get());
		}
	}
}

void WindowInteractorStyle::MoveTo(Standard_Integer theX, Standard_Integer theY)
{
	if (!_occtPickerEnabled)
	{
		return;
	}

	_occtpicker->Pick(theX, theY, 0, getRenderer());

	// Traversing results
	vtkSmartPointer<vtkActorCollection> anActorCollection = _occtpicker->GetPickedActors();
	//std::cout << anActorCollection->GetNumberOfItems();

	if (anActorCollection)
	{
		// Highlight picked subshapes
		if (_shapePipelinesMap.IsEmpty())
		{
			return;
		}

		ClearHighlightAndSelection(_shapePipelinesMap, Standard_True, Standard_False);

		anActorCollection->InitTraversal();

		while (vtkActor* anActor = anActorCollection->GetNextActor())
		{
			IVtkTools_ShapeDataSource* aDataSource = IVtkTools_ShapeObject::GetShapeSource(anActor);
			if (!aDataSource)
			{
				continue;
			}

			IVtkOCC_Shape::Handle anOccShape = aDataSource->GetShape();
			if (anOccShape.IsNull())
			{
				continue;
			}

			IVtk_IdType aShapeID = anOccShape->GetId();

			Handle(Message_Messenger) anOutput = Message::DefaultMessenger();
			if (!_shapePipelinesMap.IsBound(aShapeID))
			{
				anOutput->SendWarning()
					<< "Warning: there is no VTK pipeline registered for picked shape"
					<< std::endl;
				continue;
			}

			const Handle(QIVtkSelectionPipeline)& pipeline = _shapePipelinesMap.Find(aShapeID);
			// 排除not selected actors
			if (!ContainsActor(selectActors, pipeline))
			{
				continue;
			}

			IVtk_ShapeIdList* selectedSubShapeIds = _selectedSubShapeIdsMap.Find(aShapeID);

			IVtkTools_SubPolyDataFilter* aFilter = pipeline->GetHighlightFilter();

			// 根据Shape ID获得当前Pick的所有SubShapeID
			IVtk_ShapeIdList aSubShapeIds = _occtpicker->GetPickedSubShapesIds(aShapeID);

			// If picked shape is in selected shapes then do not highlight it
			for (auto shapeID : aSubShapeIds)
			{
				if (selectedSubShapeIds->Contains(shapeID))
				{
					return;
				}
			}

			// Get ids of cells for picked subshapes.
			IVtk_ShapeIdList aSubIds;
			IVtk_ShapeIdList::Iterator aMetaIds(aSubShapeIds);
			for (; aMetaIds.More(); aMetaIds.Next())
			{
				// 获得Pick ID对应的点、面、线的ID集合
				IVtk_ShapeIdList aSubSubIds = anOccShape->GetSubIds(aMetaIds.Value());
				aSubIds.Append(aSubSubIds);
				const TopoDS_Shape& aSubShape = anOccShape->GetSubShape(aMetaIds.Value());
				//cout << "--------------------------------------------------------------" << endl;
				//cout << "Sub-shape ID: " << aMetaIds.Value() << endl;
				//cout << "Sub-shape type: " << aSubShape.TShape()->DynamicType()->Name() << endl;
			}
			aFilter->SetDoFiltering(!aSubIds.IsEmpty());
			aFilter->SetData(aSubIds);
			if (!aFilter->GetInput())
			{
				aFilter->SetInputConnection(aDataSource->GetOutputPort());
			}
			aFilter->Modified();

			pipeline->Mapper()->Update();
		}
		// 重新渲染场景
		this->GetInteractor()->GetRenderWindow()->Render();
	}
}

void WindowInteractorStyle::setVTKRenderWindow(vtkRenderWindow* vtkRenderWindow)
{
	_qvtkRenderWindow = vtkRenderWindow;
}

void WindowInteractorStyle::setRenderer(const vtkSmartPointer<vtkRenderer>& theRenderer)
{
	_renderer = theRenderer;
}

void WindowInteractorStyle::setOcctPicker(const vtkSmartPointer<IVtkTools_ShapePicker>& thePicker)
{
	_occtpicker = thePicker;
}

void WindowInteractorStyle::clearShapeMaps()
{
	_shapePipelinesMap.Clear();
	_selectedSubShapeIdsMap.Clear();
}

void WindowInteractorStyle::addPipeline(const Handle(QIVtkSelectionPipeline) pipeline, IVtk_IdType shapeID)
{
	_shapePipelinesMap.Bind(shapeID, pipeline);
	_selectedSubShapeIdsMap.Bind(shapeID, new IVtk_ShapeIdList());
}

void WindowInteractorStyle::removePipeline(IVtk_IdType id)
{
	if (!_shapePipelinesMap.IsBound(id))
	{
		return;
	}

	const Handle(QIVtkSelectionPipeline)& pipeline = _shapePipelinesMap.Find(id);
	_occtpicker->RemoveSelectableActor(pipeline->Actor());

	_shapePipelinesMap.UnBind(id);
	_selectedSubShapeIdsMap.UnBind(id);
}

void WindowInteractorStyle::ClearSelectedActors()
{
	for (Handle(QIVtkSelectionPipeline) actor : selectActors)
	{
		actor->Actor()->GetProperty()->SetColor(Colors::ActorCreated);
	}

	selectActors.clear();
	this->HighlightActor = nullptr;
	//setSelectionMode(SM_None);
}

void WindowInteractorStyle::RemoveSelectedActor(Handle(QIVtkSelectionPipeline) pipeline)
{
	if (ContainsActor(selectActors, pipeline))
	{
		pipeline->Actor()->GetProperty()->SetColor(Colors::ActorCreated);
		RemoveActor(selectActors, pipeline);

		if (selectActors.empty())
		{
			 setSelectionMode(SM_None);
		}
		if (this->HighlightActor == pipeline)
		{
			this->HighlightActor = nullptr;
		}
	}
}

VTK_ABI_NAMESPACE_END